﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Transactions;
using context;
using entities;

namespace DataAccessLibrary.DAL
{
    public class CustomerDAO
    {
        public List<Customer> SelectCustomer()
        {
            using (var ctx = new BlueMDataContext())
            {
                Table<Customer> query = ctx.Customers;

                return query.ToList();
            }
        }

        public bool InsertCustomer(Customer customer, out string account)
        {
            using (var ts = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(0, 0, 30)))
            {
                string err;
                using (var ctx = new BlueMDataContext())
                {
                    string acc = customer.CustomerAccount;
                    int pfx = 1;
                    if (!CheckCustomerAccount(acc))
                    {
                        while (!CheckCustomerAccount(acc + pfx))
                        {
                            pfx++;
                        }
                        acc = acc + pfx;
                    }
                    customer.CustomerAccount = acc;


                    if (ValidEmail(customer.CustomerEmail, "", out err))
                    {
                        ctx.Customers.InsertOnSubmit(customer);
                        ctx.SubmitChanges();

                        ts.Complete();
                        account = customer.CustomerAccount;
                        return true;
                    }
                }
                throw new Exception(err);
            }
        }

        public bool CheckCustomerEmail(string email)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Customers.FirstOrDefault(p => p.CustomerEmail == email) == null;
            }
        }

        public bool CheckCustomerAccount(string account)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Customers.FirstOrDefault(p => p.CustomerAccount == account) == null;
            }
        }

        public bool UpdateCustomer(Customer customer)
        {
            using (var ts = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(0, 0, 30)))
            {
                string err;
                using (var ctx = new BlueMDataContext())
                {
                    int id = customer.CustomerID;
                    Customer c = SelectCustomer(id);
                    c.CustomerName = customer.CustomerName;
                    c.CustomerSex = customer.CustomerSex;
                    c.ModDay = DateTime.Today;

                    if (ValidEmail(customer.CustomerEmail, c.CustomerEmail, out err))
                    {
                        ctx.SubmitChanges();
                        ts.Complete();
                        return true;
                    }
                }
                throw new Exception(err);
            }
        }

        private bool ValidEmail(string newEmail, string oldEmail, out string err)
        {
            if (oldEmail != newEmail)
            {
                if (!CheckCustomerEmail(newEmail))
                {
                    err = "Customer Email exist!";
                    return false;
                }
            }
            err = "";
            return true;
        }

        public List<Customer> SelectCustomers(string name, string email, string acount)
        {
            using (var ctx = new BlueMDataContext())
            {
                IQueryable<Customer> query = ctx.Customers;
                if (name != null)
                    query = query.Where(p => p.CustomerName.Contains(name));
                if (acount != null)
                    query = query.Where(p => p.CustomerAccount.Contains(acount));
                if (email != null)
                    query = query.Where(p => p.CustomerEmail.Contains(email));

                return query.ToList();
            }
        }


        public Customer SelectCustomer(int customerId)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Customers.First(p => p.CustomerID == customerId);
            }
        }

        public Customer SelectCustomerByEmail(string email)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Customers.First(p => p.CustomerEmail == email);
            }
        }

        public Customer SelectCustomerByAccount(string acount)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Customers.First(p => p.CustomerAccount == acount);
            }
        }

        public int CustomerCount()
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Customers.Count();
            }
        }
    }
}